package com.zhengbing.tj.service.impl;

import com.zhengbing.tj.entity.Permission;
import com.zhengbing.tj.entity.RolePermission;
import com.zhengbing.tj.entity.User;
import com.zhengbing.tj.mapper.PermissionMapper;
import com.zhengbing.tj.service.PermissionService;
import com.zhengbing.tj.service.RolePermissionService;
import com.zhengbing.tj.service.UserRoleService;
import com.zhengbing.tj.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zhengbing.tj.annotation.AuditLogRecord;
import com.zhengbing.tj.utils.JwtUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 权限服务实现类
 * 实现权限相关的业务逻辑
 *
 * @author zhengbing
 * @date 2024-08-22
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {
    
    @Autowired
    private RolePermissionService rolePermissionService;
    
    @Autowired
    private UserRoleService userRoleService;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private JwtUtils jwtUtils;
    
    @Override
    public List<Permission> getPermissionsByUserId(Long userId) {
        // 先获取用户所有角色ID
        List<Long> roleIds = userRoleService.selectRoleIdsByUserId(userId);
        if (roleIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 遍历所有角色，获取所有权限ID
        Set<Long> permissionIds = roleIds.stream()
            .flatMap(roleId -> rolePermissionService.selectPermissionIdsByRoleId(roleId).stream())
            .collect(Collectors.toSet());
        
        if (permissionIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 根据权限ID列表查询权限信息
        return listByIds(permissionIds);
    }
    
    @Override
    public List<Permission> getPermissionsByRoleId(Long roleId) {
        // 根据角色ID查询权限ID列表
        List<Long> permissionIds = rolePermissionService.selectPermissionIdsByRoleId(roleId);
        if (permissionIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 根据权限ID列表查询权限信息
        return listByIds(permissionIds);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    @AuditLogRecord(entityType = "role_permission", operationType = "update", description = "更新角色权限关系", idParamIndex = 0)
    public void saveRolePermissions(Long roleId, List<Long> permissionIds) {
        // 先删除角色原有的权限关系
        rolePermissionService.removeByRoleId(roleId);
        
        // 保存新的角色权限关系
        if (permissionIds != null && !permissionIds.isEmpty()) {
            List<RolePermission> rolePermissions = permissionIds.stream().map(permissionId -> {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setRoleId(roleId);
                rolePermission.setPermissionId(permissionId);
                return rolePermission;
            }).collect(Collectors.toList());
            
            // 使用批量插入，提高性能
            rolePermissionService.saveBatch(rolePermissions);
        }
    }
    
    @Override
    public boolean hasPermission(Long userId, String permissionCode) {
        // 查询用户的所有权限
        List<Permission> permissions = getPermissionsByUserId(userId);
        
        // 检查是否包含目标权限
        Set<String> permissionCodes = permissions.stream()
            .map(Permission::getCode)
            .collect(Collectors.toSet());
        
        return permissionCodes.contains(permissionCode);
    }
    
    @Override
    public List<Permission> getPermissionsByToken(String token) {
        // 解析token获取用户名
        String username = jwtUtils.getUsernameFromToken(token);
        if (username == null || username.isEmpty()) {
            throw new IllegalArgumentException("Invalid token: username cannot be empty");
        }
        
        // 根据用户名获取用户信息
        User user = userService.getUserByUsername(username);
        if (user == null) {
            throw new IllegalArgumentException("User not found with username: " + username);
        }
        
        // 根据用户ID获取权限列表
        return getPermissionsByUserId(user.getId());
    }
}